/**
 * Copyright (c) 2020 kedacom
 * OpenATC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 **/
package com.openatc.agent.service;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.openatc.agent.model.THisParams;
import com.openatc.extend.common.aop.model.WebOperationRecord;
import com.openatc.agent.model.WebOperationRecordRange;
import com.openatc.agent.resmodel.PageOR;
import com.openatc.agent.service.impl.CommonService;
import com.openatc.agent.utils.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import static com.openatc.extend.common.aop.model.WebOperationRecord.TABLE_NAME;


/**
 * @author zs
 * @ClassName: ParamServiceImpl
 * @Description: 历史操作记录实现类
 * @date 2019年10月19日 下午5:43:40
 */
@Repository
public class HisParamServiceImpl {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired(required = false)
    private THisParamsDao thisParamsDao;

    @Autowired
    private AscsDao ascsDao;

    @Autowired
    private CommonService commonService;

    /**
     * @param tParams 历史记录
     * @return RESTRetBase
     * @Title: putTscParam
     * @Description: 添加一条操作记录
     */
    public int insertHisParam(THisParams tParams) {
        if (tParams == null) return 0;
        try {
            thisParamsDao.save(tParams);
            return 1;
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * @return RESTRetBase
     * @Title: putTscParam
     * @Description: 获取所有的操作记录
     */
    public List<THisParams> getAllHisList() {
        return null;
    }


    /**
     * @param uuid 记录ID
     * @return RESTRetBase
     * @Title: putTscParam
     * @Description: 获取一条操作记录
     */
    public THisParams getHisList(String uuid) {
        THisParams hisParams = null;
        return hisParams;
    }


    /**
     * @param uuid 记录ID
     * @return RESTRetBase
     * @Title: putTscParam
     * @Description: 删除一条操作记录
     */
    public int deleteParams(String uuid) {
        return 0;
    }


    /**
     * 根据路口角色获取对应设备id
     * @return
     */
    public List<String> getAgentidListByUserRole() {
        String whereCondition = "";
        String code = ascsDao.getSqlByUserRole();
        if (code != null){
            String temp = code;
            whereCondition = ascsDao.addWhereCondition(whereCondition,temp);
        }

        String sql = "SELECT agentid FROM dev";
        sql = sql.concat(whereCondition);
        List<String> agentids = ascsDao.getAgentidsBySql(sql);
        return agentids;
    }

    /**
     * 保存平台操作记录
     * @param record
     * @return
     */
    public int saveRecord(WebOperationRecord record) {
        Gson gson = new GsonBuilder().create();
        String sql = String.format("insert into %s (opertime,operator,source,status,requestbody,responsebody,model,infotype,requestsource) values " +
                "(LOCALTIMESTAMP,'%s','%s',%s,'%s','%s','%s','%s',%s)",
                TABLE_NAME,record.getOperator(),record.getSource(),record.getStatus(),gson.toJson(record.getRequestbody()),gson.toJson(record.getResponsebody()),record.getModel(),record.getInfotype(),record.getRequestsource());
        int count = jdbcTemplate.update(sql);
        return count;
    }

    /**
     * 获取平台操作记录
     * @param range
     * @return
     */
    public PageOR<WebOperationRecord> getPlatformOperationRecord(WebOperationRecordRange range) {
        String userName = TokenUtil.getCurrentUserName();
        // 获取不到用户名，赋管理员用户
        if (userName == null) {
            userName = "admin";
        }
        // 管理员可以看到所有的操作记录,非管理员只可以看到自己的操作记录
        String tableName = TABLE_NAME;
        String baseSql = String.format("select id,opertime,operator,source,status,model,infotype from %s ",tableName);

        String roleCondition = createRoleCondition(userName);

        String whereCondition = getOperationWhereCondition(range,roleCondition);

        String limitCondition = createLimitCondition(range.getPageNum(),range.getPageRow());

        String orderBy = " ORDER BY opertime desc ";
        String countBase = String.format("select count(*) from %s ",tableName);

        String countSql = countBase.concat(whereCondition);

        String searchSql = baseSql.concat(whereCondition).concat(orderBy).concat(limitCondition);

        int count = jdbcTemplate.queryForObject(countSql, int.class);
        PageOR<WebOperationRecord> pageOR = new PageOR<>();

        List<WebOperationRecord> records = jdbcTemplate.query(searchSql, new RowMapper<WebOperationRecord>() {
            @Override
            public WebOperationRecord mapRow(ResultSet rs, int rowNum) throws SQLException {
                WebOperationRecord record = new WebOperationRecord();
                record.setId(rs.getInt("id"));
                record.setOperator(rs.getString("operator"));
                record.setOpertime(rs.getTimestamp("opertime"));
                record.setSource(rs.getString("source"));
                record.setModel(rs.getString("model"));
                record.setInfotype(rs.getString("infotype"));
                record.setStatus(rs.getInt("status"));
                return record;
            }
        });

        pageOR.setTotal((long)count);
        pageOR.setContent(records);

        return pageOR;

    }

    private String createLimitCondition(Integer pageNum, Integer pageRow) {
        String limit = "";
        if (pageNum != null && pageRow != null) {
            int pageNum1 = pageNum - 1;
            if (pageNum1 < 0)
                pageNum1 = 0;
            limit = String.format(" limit  %d  offset  %d ",pageRow, pageNum1 * pageRow );
        }
        return limit;
    }

    private String getOperationWhereCondition(WebOperationRecordRange range, String roleCondition) {
        String where = "";
        String tmp = "";
        where = commonService.addWhereCondition(roleCondition,tmp);
        // 模块
        if (StringUtils.hasLength(range.getModel())) {
            tmp = String.format(" model = '%s'",range.getModel());
            where = commonService.addWhereCondition(where,tmp);
        }
        // 类型
        if (StringUtils.hasLength(range.getInfotype())) {
            tmp = String.format(" infotype = '%s'",range.getInfotype());
            where = commonService.addWhereCondition(where,tmp);
        }
        // 操作者
        if (StringUtils.hasLength(range.getOperator())) {
            tmp = String.format(" operator = '%s'",range.getOperator());
            where = commonService.addWhereCondition(where,tmp);
        }
        // 应答状态
        if (range.getStatus() != null) {
            tmp = String.format(" status = %s",range.getStatus());
            where = commonService.addWhereCondition(where,tmp);
        }

        if (StringUtils.hasLength(range.getBeginTime()) && StringUtils.hasLength(range.getEndTime())) {
            tmp = String.format(" opertime between '%s' and '%s'",range.getBeginTime(),range.getEndTime());
            where = commonService.addWhereCondition(where,tmp);
        }
//        // 请求来源  null/0:只获取开源版的模块记录   1:获取所有模块记录
//        if (range.getRequestsource() == null || range.getRequestsource() == 0) {
//            tmp = String.format(" requestsource = 0");
//            where = commonService.addWhereCondition(where,tmp);
//        }
        return where;
    }

    private String createRoleCondition(String userName) {
        String roleCondition = String.
                format("where (CASE " +
                                " WHEN ( SELECT userrole FROM (SELECT r.name userrole FROM t_role r JOIN t_user_role ur ON r.id = ur.role_id" +
                                            " JOIN t_user u ON ur.user_id = u.id  WHERE u.user_name = '%s') as usr1 WHERE position('superadmin' in usr1.userrole) > 0) NOTNULL" +
                                " THEN 1 = 1" +
                                " WHEN ( SELECT userrole FROM (SELECT r.name userrole FROM t_role r JOIN t_user_role ur  ON r.id = ur.role_id JOIN t_user u" +
                                            " ON ur.user_id = u.id WHERE u.user_name = '%s') as usr1 WHERE position('admin' in usr1.userrole) > 0) NOTNULL" +
                                " THEN 1 = 1" +
                                " ELSE operator='%s' END)",userName,userName,userName);
        return roleCondition;
    }

    /**
     * 获取平台指定的操作记录
     * @param id
     * @return
     */
    public WebOperationRecord getPlatformOperationRecordById(Integer id) {
        Gson gson = new GsonBuilder().create();
        String tableName = TABLE_NAME;
        String sql = String.format("select id,opertime,operator,source,status,requestbody,responsebody,model,infotype,requestsource from %s where id = %s",tableName,id);
        List<WebOperationRecord> records = jdbcTemplate.query(sql, new RowMapper<WebOperationRecord>() {
            @Override
            public WebOperationRecord mapRow(ResultSet rs, int rowNum) throws SQLException {
                WebOperationRecord record = new WebOperationRecord();
                record.setId(rs.getInt("id"));
                record.setOperator(rs.getString("operator"));
                record.setOpertime(rs.getTimestamp("opertime"));
                record.setSource(rs.getString("source"));
                record.setModel(rs.getString("model"));
                record.setInfotype(rs.getString("infotype"));
                record.setStatus(rs.getInt("status"));
                record.setRequestbody(gson.fromJson(rs.getString("requestbody"), JsonElement.class));
                record.setResponsebody(gson.fromJson(rs.getString("responsebody"),JsonElement.class));
                record.setRequestsource(rs.getInt("requestsource"));
                return record;
            }
        });
        if (!CollectionUtils.isEmpty(records)) {
            return records.get(0);
        }
        return null;
    }
}
